home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
xpaint-2.1.1
/
Colormap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
7KB
|
233 lines
/* +-------------------------------------------------------------------+ */
/* | Copyright 1992, 1993, David Koblas (koblas@netcom.com) | */
/* | | */
/* | Permission to use, copy, modify, and to distribute this software | */
/* | and its documentation for any purpose is hereby granted without | */
/* | fee, provided that the above copyright notice appear in all | */
/* | copies and that both that copyright notice and this permission | */
/* | notice appear in supporting documentation. There is no | */
/* | representations about the suitability of this software for | */
/* | any purpose. this software is provided "as is" without express | */
/* | or implied warranty. | */
/* | | */
/* +-------------------------------------------------------------------+ */
#include <math.h>
#include <X11/IntrinsicP.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>
#include "ColormapP.h"
static XtResource resources[] = {
#define offset(field) XtOffset(ColormapWidget, color.field)
{ XtNcallback, XtCCallback, XtRCallback, sizeof(XtPointer),
offset(callbacks), XtRCallback, (XtPointer)None },
{ XtNcolor, XtCColor, XtRPixel, sizeof(Pixel),
offset(pixel), XtRImmediate, (XtPointer)None },
{ XtNreadOnly, XtCReadOnly, XtRBoolean, sizeof(Boolean),
offset(editable), XtRImmediate, (XtPointer)False },
{ XtNcellWidth, XtCCellWidth, XtRInt, sizeof(int),
offset(cwidth), XtRImmediate, (XtPointer)5 },
{ XtNcellHeight, XtCCellHeight, XtRInt, sizeof(int),
offset(cheight), XtRImmediate, (XtPointer)5 },
{ XtNthickness, XtCThickness, XtRInt, sizeof(int),
offset(thickness), XtRImmediate, (XtPointer)1 },
{ XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
offset(foreground), XtRString, XtDefaultForeground },
#undef offset
};
static void ResizeProc(ColormapWidget);
static void ExposeProc(ColormapWidget, XExposeEvent *);
static void InitializeProc(ColormapWidget, ColormapWidget);
static Boolean SetValuesProc(Widget, Widget, Widget);
static void drawSelection(ColormapWidget w, int flag)
{
XGCValues values;
int x, y;
GC gc;
int t = w->color.thickness, t2 = t / 2 + 1;
values.line_width = w->color.thickness;
if (flag) {
values.foreground = w->color.foreground;
values.background = w->core.background_pixel;
} else {
values.foreground = w->core.background_pixel;
values.background = w->color.foreground;
}
gc = XtGetGC((Widget)w, GCForeground|GCBackground|GCLineWidth, &values);
x = (w->color.pixel % w->color.ncwidth) * w->color.cwidth;
y = (w->color.pixel / w->color.ncwidth) * w->color.cheight;
XDrawRectangle(XtDisplay(w), XtWindow(w), gc,
x - t2, y - t2, w->color.cwidth, w->color.cheight);
}
static void ColormapSelect(ColormapWidget w, XEvent* e,
String* str, Cardinal* n)
{
int pixel;
XColor col;
if ((e->xbutton.x / w->color.cwidth) > w->color.ncwidth)
return;
if ((e->xbutton.y / w->color.cheight) > w->color.ncheight)
return;
pixel = (e->xbutton.y / w->color.cheight) * w->color.ncwidth;
pixel += e->xbutton.x / w->color.cwidth;
drawSelection(w, FALSE);
w->color.pixel = pixel;
drawSelection(w, TRUE);
col.pixel = pixel;
col.flags = DoRed|DoGreen|DoBlue;
XQueryColor(XtDisplay(w), w->core.colormap, &col);
XtCallCallbackList((Widget)w, w->color.callbacks, (XtPointer)&col);
}
static XtActionsRec actions[] =
{
/* {name, procedure}, */
{"Set", (XtActionProc)ColormapSelect},
};
static char translations[] =
"<BtnDown>: Set() \n\
";
ColormapClassRec colormapClassRec = {
{ /* core fields */
/* superclass */ (WidgetClass) &widgetClassRec,
/* class_name */ "Colormap",
/* widget_size */ sizeof(ColormapRec),
/* class_initialize */ NULL,
/* class_part_initialize */ NULL,
/* class_inited */ FALSE,
/* initialize */ (XtInitProc)InitializeProc,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ actions,
/* num_actions */ XtNumber(actions),
/* resources */ resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave */ TRUE,
/* visible_interest */ FALSE,
/* destroy */ NULL,
/* resize */ (XtWidgetProc)ResizeProc,
/* expose */ (XtExposeProc)ExposeProc,
/* set_values */ (XtSetValuesFunc)SetValuesProc,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ translations,
/* query_geometry */ XtInheritQueryGeometry,
/* display_accelerator */ XtInheritDisplayAccelerator,
/* extension */ NULL
},
{ /* colormap fields */
/* empty */ 0
}
};
WidgetClass colormapWidgetClass = (WidgetClass)&colormapClassRec;
static void InitializeProc(ColormapWidget w, ColormapWidget new)
{
Widget shell = XtParent(w);
Visual *visual = NULL;
while (!XtIsShell(shell))
shell = XtParent(shell);
XtVaGetValues(shell, XtNvisual, &visual, NULL);
if (visual == NULL)
visual = DefaultVisualOfScreen(XtScreen(w));
new->color.ncel = visual->map_entries;
new->color.ncwidth = (int)sqrt((double)new->color.ncel);
new->color.ncheight = (new->color.ncel + new->color.ncwidth - 1) /
new->color.ncwidth;
if (new->core.width == 0)
new->core.width = new->color.cwidth * new->color.ncwidth;
else
new->color.cwidth = (int)new->core.width / (int)new->color.ncwidth;
if (new->core.height == 0)
new->core.height = new->color.cheight * new->color.ncheight;
else
new->color.cheight = new->core.height / new->color.ncheight;
}
static void ResizeProc(ColormapWidget w)
{
w->color.cwidth = w->core.width / w->color.ncwidth;
w->color.cheight = w->core.height / w->color.ncheight;
}
static void ExposeProc(ColormapWidget w, XExposeEvent *event)
{
Display *dpy = XtDisplay(w);
Window win = XtWindow(w);
GC gc = XCreateGC(dpy, win, 0, NULL);
int color = 0;
int x, y, X, Y;
int nvert = w->color.ncwidth;
int nhoriz = w->color.ncheight;
int t = w->color.thickness;
for (Y = y = 0; y < nhoriz; y++, Y += w->color.cheight) {
for (X = x = 0; x < nvert; x++, X += w->color.cwidth) {
XSetForeground(dpy, gc, color++);
XFillRectangle(dpy, win, gc, X, Y,
w->color.cwidth - 1 - t, w->color.cheight - 1 - t);
}
}
XFreeGC(dpy, gc);
drawSelection(w, TRUE);
}
static Boolean SetValuesProc(Widget curArg, Widget request, Widget newArg)
{
ColormapWidget cur = (ColormapWidget)curArg;
ColormapWidget new = (ColormapWidget)newArg;
if (cur->color.pixel != new->color.pixel) {
drawSelection(cur, FALSE);
drawSelection(new, TRUE);
}
return False;
}
void CwGetColor(Widget cw, XColor* col)
{
ColormapWidget w = (ColormapWidget)cw;
col->pixel = w->color.pixel;
col->flags = DoRed|DoGreen|DoBlue;
XQueryColor(XtDisplay(w), w->core.colormap, col);
}
void CwSetColor(Widget cw, XColor* col)
{
ColormapWidget w = (ColormapWidget)cw;
col->pixel = w->color.pixel;
XStoreColor(XtDisplay(w), w->core.colormap, col);
}